import 'package:dio/dio.dart';

/// 网络请求单例工具类
class Request {
  // 单例
  static Request _instance;
  // 构造方法调用实例化方法
  factory Request() => _getInstance();
  static Request get instance => _getInstance();
  // 单例
  static Request _getInstance() {
    if (_instance == null) {
      _instance = new Request._internal();
    }
    return _instance;
  }

  // DIO对象
  Dio _dio;

  /// 初始化当前工具类
  Request._internal() {
    // 初始化
    _dio = _createDio();
  }

  /// 创建 DIO 对象
  Dio _createDio() {
    // 创建 DIO
    Dio dio = Dio();
    // 设置连接超时时间
    dio.options.connectTimeout = 10000;
    // 设置发送超时时间
    dio.options.sendTimeout = 20000;
    // 设置响应超时时间
    dio.options.receiveTimeout = 20000;
    // 实际项目中设置 baseUrl
    // dio.options.baseUrl = 'https://ww.baidu.com/';
    // 设置拦截器
    dio.interceptors.add(InterceptorsWrapper(
        // 请求拦截
        onRequest: (RequestOptions options) {
      print('request: ${options.uri}');
      return options;
    },
        // 响应拦截
        onResponse: (Response response) {
      print('response: $response');
      return response;
    },
        // 异常
        onError: (DioError e) {
      print('error: ${e.message}');
      return e;
    }));
    return dio;
  }

  /// GET 请求
  /// @param url 请求地址
  /// @param params 请求参数
  /// @param successCallback 成功回调
  /// @param errorCallback 失败回调
  void get(
      {String url,
      Map<String, dynamic> params,
      Function successCallback,
      Function errorCallback}) async {
    try {
      // 请求获取响应
      Response response = await _dio.get(url, queryParameters: params);
      // 结果响应处理
      _handleResponse(response, successCallback, errorCallback);
    } catch (e) {
      // 失败响应处理
      _handleError(e.toString(), errorCallback);
    }
  }

  /// POST 请求
  /// @param url 请求地址
  /// @param queryParams 请求参数
  /// @param data 参数
  /// @param successCallback 成功回调
  /// @param errorCallback 失败回调
  void post(
      {String url,
      Map<String, dynamic> params,
      dynamic data,
      Function successCallback,
      Function errorCallback}) async {
    try {
      // 获取网络数据
      Response response =
          await _dio.post(url, queryParameters: params, data: data);
      // 处理响应
      _handleResponse(response, successCallback, errorCallback);
    } catch (e) {
      // 失败响应处理
      _handleError(e.toString(), errorCallback);
    }
  }

  /// 响应处理
  /// @param response 响应结果
  /// @param successCallback 成功处理
  /// @param errorCallback 失败处理
  _handleResponse(
      Response response, Function successCallback, Function errorCallback) {
    // 检测响应码
    if (response.statusCode == 200 && null != successCallback) {
      // 将服务器端 JSON 数据转换为 Map
      // Map<String, dynamic> json = jsonDecode(response.toString());
      // Map<String, dynamic> json = jsonDecode(response.data.toString());
      // 成功回调
      successCallback(response.toString());
    } else {
      // 错误处理
      _handleError('网络请求错误,状态码: ${response.statusCode}', errorCallback);
    }
  }

  /// 异常处理
  /// @param msg 异常信息
  /// @param errorCallback 错误回调
  _handleError(String msg, Function errorCallback) {
    // 判断是否有异常回调
    if (null != errorCallback) {
      errorCallback(msg);
    }
    print('<net> errorMsg : $msg');
  }
}
